/**
 * 
 */
package sudoku.util.game;

import java.util.ArrayList;
import java.util.List;

import javax.swing.JDialog;
import javax.swing.Timer;

import sudoku.controller.Controller;
import sudoku.model.SudokuModel;
import sudoku.ui.SudokuUI;
import sudoku.util.Config;
import sudoku.util.Language;

/**
 * @author Romet
 * 
 */
public class GenerateNewGame implements Runnable {

  private volatile SudokuModel model;
  private volatile Config config;
  private volatile Language language;
  private volatile SudokuUI m2ng;
  private volatile Controller controller;

  private volatile JDialog d;
  private volatile Timer timer;

  public volatile boolean done;
  private int mode;

  public GenerateNewGame(SudokuModel model, Config config, Language language, int mode) {
    this.model = model;
    this.config = config;
    this.language = language;
    this.mode = mode;
  }

  public void setController(Controller controller) {
    this.controller = controller;
  }

  public void setD(JDialog d) {
    this.d = d;
  }

  public void setTimer(Timer timer) {
    this.timer = timer;
  }

  public void setM2ng(SudokuUI m2ng) {
    this.m2ng = m2ng;
  }

  /*
   * (non-Javadoc)
   * 
   * @see java.lang.Runnable#run()
   */
  @Override
  public void run() {
    if (mode == 1) {
      done = false;
      while (!done && model.isGenerationNeeded()) {
        SolveDLX sdlx = new SolveDLX(config.getRuudustik());
        sdlx.game = this;
        sdlx.BuildSudokuMatrix();
        if (config.isSymma()) {
          sdlx.create();
        } else {
          List<String> list = new ArrayList<String>();
          if (config.isSymm90()) {
            list.add("symm90");
          }
          if (config.isSymm180()) {
            list.add("symm180");
          }
          if (config.isSymm270()) {
            list.add("symm270");
          }
          if (config.isSymmvert()) {
            list.add("symmvert");
          }
          if (config.isSymmdiaga()) {
            list.add("symmdiaga");
          }
          if (config.isSymmhor()) {
            list.add("symmhor");
          }
          if (config.isSymmdiagm()) {
            list.add("symmdiagm");
          }
          sdlx.createSymmetric(list);
        }
        if (!done) {
          model.setGenerating(true);
          String s = sdlx.getSolution();
          model.lahendaHindaM2ng(s);
          model.setGenerating(false);
          boolean salvesta = false;
          if (model.getGenLevel().equals(language.getSudoku_diffeasy()) && config.getEasy().size() < 3) {
            config.getEasy().add(s);
            salvesta = true;
          } else if (model.getGenLevel().equals(language.getSudoku_diffmedium()) && config.getMedium().size() < 10) {
            config.getMedium().add(s);
            salvesta = true;
          } else if (model.getGenLevel().equals(language.getSudoku_diffhard()) && config.getHard().size() < 10) {
            config.getHard().add(s);
            salvesta = true;
          } else if (model.getGenLevel().equals(language.getSudoku_diffexpert()) && config.getExpert().size() < 10) {
            config.getExpert().add(s);
            salvesta = true;
          } else if (model.getGenLevel().equals(language.getSudoku_diffextreme()) && config.getExtreme().size() < 10) {
            config.getExtreme().add(s);
            salvesta = true;
          }
          if (salvesta) {
            config.salvesta();
          }
        }
      }
      timer.stop();
      d.dispose();
      m2ng.setEnabled(true);
      m2ng.requestFocus();
      if (!done) {
        String level = model.getLevel();
        controller.handleEvent(Controller.UUS_M2NG_EVENT);
        model.setLevel(level);
        String s = model.getLevel();
        if (s.equals(language.getSudoku_diffeasy())) {
          model.setLahendus(config.getEasy().remove(0));
        } else if (s.equals(language.getSudoku_diffmedium())) {
          model.setLahendus(config.getMedium().remove(0));
        } else if (s.equals(language.getSudoku_diffhard())) {
          model.setLahendus(config.getHard().remove(0));
        } else if (s.equals(language.getSudoku_diffexpert())) {
          model.setLahendus(config.getExpert().remove(0));
        } else if (s.equals(language.getSudoku_diffextreme())) {
          model.setLahendus(config.getExtreme().remove(0));
        }
        config.salvesta();
        controller.handleEvent(Controller.ALUSTA_M2NG_EVENT);
      }
      m2ng.uuendaUI();
      m2ng.requestFocus();
      done = true;
    } else if (mode == 2) {
      String s = model.getLevel();
      while (model.thread.isAlive()) {
        if (s.equals(language.getSudoku_diffeasy()) && config.getEasy().size() > 0) {
          model.generate.done = true;
        } else if (s.equals(language.getSudoku_diffmedium()) && config.getMedium().size() > 0) {
          model.generate.done = true;
        } else if (s.equals(language.getSudoku_diffhard()) && config.getHard().size() > 0) {
          model.generate.done = true;
        } else if (s.equals(language.getSudoku_diffexpert()) && config.getExpert().size() > 0) {
          model.generate.done = true;
        } else if (s.equals(language.getSudoku_diffextreme()) && config.getExtreme().size() > 0) {
          model.generate.done = true;
        }
        try {
          Thread.sleep(100);
        } catch (Exception e) {
          Config.log(e.getClass().toString() + ": " + e.getMessage(), e.getStackTrace());
        }
      }
      d.dispose();
      m2ng.setEnabled(true);
      m2ng.requestFocus();
      if (s.equals(language.getSudoku_diffeasy())) {
        model.setLahendus(config.getEasy().remove(0));
      } else if (s.equals(language.getSudoku_diffmedium())) {
        model.setLahendus(config.getMedium().remove(0));
      } else if (s.equals(language.getSudoku_diffhard())) {
        model.setLahendus(config.getHard().remove(0));
      } else if (s.equals(language.getSudoku_diffexpert())) {
        model.setLahendus(config.getExpert().remove(0));
      } else if (s.equals(language.getSudoku_diffextreme())) {
        model.setLahendus(config.getExtreme().remove(0));
      }
      config.salvesta();
      controller.handleEvent(Controller.ALUSTA_M2NG_EVENT);
      m2ng.uuendaUI();
      m2ng.requestFocus();
    }
  }
}
